package com.ftg.learn.chapter09.base02.util;

import com.ftg.learn.chapter04.isa.Dog;
import com.ftg.learn.chapter09.base01.Flies;
import com.ftg.learn.chapter09.base02.annotation.Column;
import com.ftg.learn.chapter09.base02.annotation.Id;
import com.ftg.learn.chapter09.base02.annotation.TableName;
import com.ftg.learn.chapter09.base02.entity.TeacherEntity;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author 布衣
 */
public class BaseDao<E> {

    private JdbcUtil<E> jdbcUtil = new JdbcUtil<>();

    private E e1;

    public BaseDao(E e1) {
        this.e1 = e1;
    }

    private String createQuerySql() {
        Class<?> aClass = e1.getClass();
        TableName annotation = aClass.getAnnotation(TableName.class);

        //获取所有类 类的名称  类的注解里面的值
        Field[] declaredFields = aClass.getDeclaredFields();
        String clName = "";
        for (Field field : declaredFields) {
            String otherName = field.getName();
            String columnName = field.getAnnotation(Column.class) == null ? null : field.getAnnotation(Column.class).value();
            String columnName1 = field.getAnnotation(Id.class) == null ? null : field.getAnnotation(Id.class).value();
            clName += (columnName == null ? (columnName1 == null ? otherName : columnName1) : columnName) + " " + otherName + " , ";
        }
        clName = clName.substring(0, clName.lastIndexOf(","));
        return "select " + clName + " from " + annotation.value();
    }

    public String createDelSql() {
        Class<?> aClass = e1.getClass();
        TableName annotation = aClass.getAnnotation(TableName.class);
        Field[] declaredFields = aClass.getDeclaredFields();
        String sql = "delete from " + annotation.value() + " where ";
        for (Field field : declaredFields) {
            String otherName = field.getName();
            Id id = field.getAnnotation(Id.class);
            if (id != null) {
                sql += id.value() + " = ?";
                break;
            }
        }
        System.out.println(sql);
        return sql;
    }

    public int saveEntity(E obj) {
        return jdbcUtil.update(createInsertSql(obj), createParams(obj));
    }

    private Object[] createParams(E obj) {
        List<Object> list = new ArrayList<>();
        Field[] alls = obj.getClass().getDeclaredFields();
        for (Field all : alls) {
            try {
                all.setAccessible(true);
                Object o = all.get(obj);
                if(o != null){
                    list.add(o);
                }
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return list.toArray();
    }

    private String createInsertSql(E obj) {
        StringBuilder sql = new StringBuilder("insert into ");
        Class<E> target = (Class<E>) obj.getClass();
        TableName annotation = target.getAnnotation(TableName.class);
        sql.append(annotation.value()).append(" ( ");
        Field[] alls = target.getDeclaredFields();
        String ask = "";
        for (Field all : alls) {
            try {
                all.setAccessible(true);
                Object o = all.get(obj);
                if (o != null) {
                    String word = "";
                    Id id = all.getAnnotation(Id.class);
                    if (id != null) {
                        word = id.value();
                    }
                    Column c = all.getAnnotation(Column.class);
                    if (c != null) {
                        word = c.value();
                    }
                    if (c == null && id == null) {
                        word = all.getName();
                    }
                    sql.append(word).append(",");
                    ask += "?,";
                }
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        ask = ask.substring(0, ask.length() - 1);
        return sql.substring(0, sql.length() - 1) + ") values(" + ask + ")";
    }

    public int delById(Integer id) {
        return jdbcUtil.update(this.createDelSql(), id);
    }

    public List<Map<String, Object>> list() {
        return jdbcUtil.query(this.createQuerySql());
    }

    public static void main(String[] args) {
        //base + jdbcutil : 叫做orm框架
        //Hibernate S(struct1.1)S(spring2.0)H(Hibernate) Ss2Ss2Mmybatis springboot springmvc spring Mybatis (ssm) SSI
        //ORM Hibernate (必须要会的) HQL(。。。。sql) Ibatis(半自动) Louts[] google() Mybatis(半自动) 5.X oracle 8 (..)  [sql]
        BaseDao<TeacherEntity> baseDao = new BaseDao<>(new TeacherEntity());
        TeacherEntity t = new TeacherEntity();
        t.setTeacherName("abc");
        baseDao.saveEntity(t);
    }

}
